package org.kca.yarmour.view;

import static org.lwjgl.opengl.GL11.*;

import java.awt.Color;
import java.awt.Font;

import org.kca.graphics.FontPalette;
import org.kca.graphics.IController;
import org.kca.yarmour.utils.ImageUtils;
import org.kca.yarmour.utils.KcaGLUtils;
import org.lwjgl.input.Mouse;

public abstract class PopupDialog implements IController, DialogListener, MouseAccess
{
    public static final int ACTION_DIALOG_CLOSED = 1;
    public static final int ACTION_OK_PRESSED = 2;
    public static final int ACTION_CANCEL_PRESSED = 3;
    protected static final int TITLEBAR_HEIGHT = 22;
    protected static final int BORDER_WIDTH = 2;
    protected static final FontPalette TITLEBAR_FONT = new FontPalette(new Font(
            "Times New Roman", Font.BOLD, 16));
    protected static final FontPalette DIALOG_FONT = new FontPalette(new Font(
            "Times New Roman", Font.PLAIN, 14));
    protected static final Color DEFAULT_BGCOLOR = new Color(234, 234, 234);
    protected static final Color DEFAULT_BORDERCOLOR1 = new Color(128, 128, 128);
    protected static final Color DEFAULT_BORDERCOLOR2 = Color.black;
    protected static final Color DEFAULT_TITLEBARCOLOR = new Color(159, 183, 203);
    
    private int width, height, x, y;
    private String title;
    private Color bgColor = DEFAULT_BGCOLOR;
    private Color borderColor1 = DEFAULT_BORDERCOLOR1;
    private Color borderColor2 = DEFAULT_BORDERCOLOR2;
    private Color titlebarColor = DEFAULT_TITLEBARCOLOR;
    private DialogListener listener;
    private MouseAccess mouseAccessProvider;
    
    public PopupDialog(int width, int height)
    {
        this(width, height, "Dialog");
    }
    
    public PopupDialog(int width, int height, String title)
    {
        this.width = width;
        this.height = height;
        this.title = title;
        width = Math.max(width, TITLEBAR_FONT.stringWidth(title) + 2);
        height = Math.max(height, TITLEBAR_HEIGHT * 2);
        listener = null;
        mouseAccessProvider = null;
    }
    
    /**
     * Sets the dialog listener for this dialog box
     * @param dl the dialog listener
     */
    public void setDialogListener(DialogListener dl)
    {
        this.listener = dl;
    }
    
    /**
     * Gets the dialog listener for this dialog box
     * @return the dialog listener
     */
    public DialogListener getDialogListener()
    {
        return listener;
    }
    
    /**
     * Sets the mouse access provider. If not provided, will treat the coordinate frame to be
     * at 0, 0
     * @param ma the mouse access provider
     */
    public void setMouseAccessProvider(MouseAccess ma)
    {
        mouseAccessProvider = ma;
    }
    
    /**
     * Gets the x
     * @return the x
     */
    public int getX()
    {
        return x;
    }

    /**
     * Sets the x
     * @param x the x to set
     */
    public void setX(int x)
    {
        this.x = x;
    }

    /**
     * Gets the y
     * @return the y
     */
    public int getY()
    {
        return y;
    }

    /**
     * Sets the y
     * @param y the y to set
     */
    public void setY(int y)
    {
        this.y = y;
    }

    /**
     * Gets the width
     * @return the width
     */
    public int getWidth()
    {
        return width;
    }

    /**
     * Sets the width
     * @param width the width to set
     */
    public void setWidth(int width)
    {
        this.width = width;
    }

    /**
     * Gets the height
     * @return the height
     */
    public int getHeight()
    {
        return height;
    }

    /**
     * Sets the height
     * @param height the height to set
     */
    public void setHeight(int height)
    {
        this.height = height;
    }
    
    /**
     * Gets the title
     * @return the title of the dialog
     */
    public String getTitle()
    {
        return title;
    }

    @Override
    public void drawComponent(int x, int y)
    {
        glPushMatrix();
        glTranslatef(this.x, this.y, 0);
        drawBase();
        drawContent();
        glPopMatrix();
    }
    
    /**
     * Draws the base graphics of the dialog box
     */
    protected void drawBase()
    {
        KcaGLUtils.setColor(bgColor);
        KcaGLUtils.fillRect(0, 0, width, height);
        KcaGLUtils.setColor(titlebarColor);
        KcaGLUtils.fillRect(0, 0, width, TITLEBAR_HEIGHT);
        KcaGLUtils.setColor(borderColor1);
        KcaGLUtils.drawRect(0, 0, width, height);
        KcaGLUtils.setColor(borderColor2);
        KcaGLUtils.drawRect(1, 1, width - 2, height - 2);
        KcaGLUtils.drawLine(1, TITLEBAR_HEIGHT, width - 1, TITLEBAR_HEIGHT);
        // write dialog title
        int centerX = ImageUtils.centerAlignX(TITLEBAR_FONT, 0, width - TITLEBAR_HEIGHT, title);
        TITLEBAR_FONT.drawString(title, centerX, 2);
        // draw X on top right
        KcaGLUtils.setColor(borderColor2);
        KcaGLUtils.drawLine(width - TITLEBAR_HEIGHT + 1, 1, width - TITLEBAR_HEIGHT + 1, 
                TITLEBAR_HEIGHT);
        KcaGLUtils.drawLine(width - TITLEBAR_HEIGHT, 1, width - 1, TITLEBAR_HEIGHT);
        KcaGLUtils.drawLine(width - 1, 1, width - TITLEBAR_HEIGHT, TITLEBAR_HEIGHT);
    }
    
    /**
     * Draws the main content of the dialog box. Should be overwritten by child classes
     */
    protected void drawContent()
    {
        
    }

    @Override
    public void update(long elapsedTime)
    {

    }

    @Override
    public void keyPressed(int keyCode, int keyChar)
    {
        
    }

    @Override
    public void keyReleased(int keyCode, int keyChar)
    {
        
    }

    @Override
    public void mousePressed(int button, int mx, int my)
    {
        if (button == 0)
        {
            if (mx > width - TITLEBAR_HEIGHT && mx < width &&
                    my > 0 && my < TITLEBAR_HEIGHT)
            {
                // X pressed
                if (listener != null)
                {
                    listener.actionPerformed(ACTION_DIALOG_CLOSED);
                }
            }
        }
    }
    
    @Override
    public void mouseHeld(int button, int mx, int my)
    {
        
    }

    @Override
    public void mouseReleased(int button, int mx, int my)
    {
        
    }
    

    @Override
    public void actionPerformed(int action)
    {
        
    }
    
    @Override
    public int getMouseX()
    {
        if (mouseAccessProvider != null)
        {
            return mouseAccessProvider.getMouseX() - getX();
        }
        else
        {
            return Mouse.getX() - getX();
        }
    }
    
    @Override
    public int getMouseY()
    {
        if (mouseAccessProvider != null)
        {
            return mouseAccessProvider.getMouseY() - getY();
        }
        else
        {
            return 768 - Mouse.getY() - getY();
        }
    }
    
    @Override
    public boolean isMouseButtonDown(int button)
    {
        if (mouseAccessProvider != null)
        {
            return mouseAccessProvider.isMouseButtonDown(button);
        }
        else
        {
            return Mouse.isButtonDown(button);
        }
    }

}
